﻿<!doctype html>
<html lang="en">
	<head>
		<title>JavaScript Patterns</title>
		<meta charset="utf-8">
	</head>
	<body>
		<script>
			/* Title: Singleton
			 Description: restricts object creation for a class to only one instance
			 */

			var obj = {
				myprop:'my value'
			};

			var obj2 = {
				myprop:'my value'
			};
			obj === obj2; // false
			obj == obj2;  // false

			var uni = new Universe();
			var uni2 = new Universe();
			uni === uni2; // true

			function Universe() {

				// do we have an existing instance?
				if (typeof Universe.instance === 'object') {
					return Universe.instance;
				}

				// proceed as normal
				this.start_time = 0;
				this.bang = "Big";

				// cache
				Universe.instance = this;

				// implicit return:
				// return this;
			}

			// testing
			var uni = new Universe();
			var uni2 = new Universe();
			uni === uni2; // true

			/*** Instance in a Closure ***/

			function Universe() {

				// the cached instance
				var instance = this;

				// proceed as normal
				this.start_time = 0;
				this.bang = "Big";

				// rewrite the contructor
				Universe = function () {
					return instance;
				};
			}

			function Universe() {

				// the cached instance
				var instance;

				// rewrite the constructor
				Universe = function Universe() {
					return instance;
				};

				// carry over the prototype properties
				Universe.prototype = this;

				// the instance
				instance = new Universe();

				// reset the constructor pointer
				instance.constructor = Universe;

				// all the functionality
				instance.start_time = 0;
				instance.bang = "Big";

				return instance;
			}


			// testing
			var uni = new Universe();
			var uni2 = new Universe();
			uni === uni2; // true

			// adding to the prototype
			Universe.prototype.nothing = true;

			var uni = new Universe();

			// again adding to the prototype
			// after the initial object is created
			Universe.prototype.everything = true;

			var uni2 = new Universe();

			// only the original prototype was
			// linked to the objects
			uni.nothing; // true
			uni2.nothing; // true
			uni.everything; // undefined
			uni2.everything; // undefined

			// that sounds right:
			uni.constructor.name; // "Universe"

			// but that's odd:
			uni.constructor === Universe; // false

			var Universe;

			(function () {

				var instance;

				Universe = function Universe() {

					if (instance) {
						return instance;
					}

					instance = this;

					// all the functionality
					this.start_time = 0;
					this.bang = "Big";
				};
			}());

			// reference
			// http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
			// http://shop.oreilly.com/product/9780596806767.do?sortby=publicationDate
		</script>
	</body>
</html>